package com.wl.springsecuritystudy.config;


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;

import java.util.Objects;
import java.util.Optional;

/**
 * jwt生成解析工具类型
 *
 */
public class JwtUtil {


    /**
     * 根据会话生产令牌
     *
     * @param session 会话
     * @return 令牌
     */
    public static Optional<String> generateJwt(SessionInfo session) {

        if (session == null || StringUtils.isBlank(session.getUserId())
                || session.getClient() == null || session.getCategory() == null) {
            return Optional.empty();
        }

        String token = Jwts.builder()
                // 主题
                .setSubject(ConstantJwt.JWT_SUBJECT)
                // 业务数据（非隐私）
                .claim(ConstantJwt.USER_ID, session.getUserId())
                .claim(ConstantJwt.USER_CATEGORY, session.getCategory())
                .claim(ConstantJwt.CLIENT_CATEGORY, session.getClient())
                .claim(ConstantJwt.LAST_REFRESH_TIMESTAMP, session.getLastRefreshTimestamp())
                // 压缩
                .compressWith(CompressionCodecs.DEFLATE)
                // 签名
                .signWith(SignatureAlgorithm.HS512, ConstantJwt.JWT_SIGNING_KEY)
                .compact();

        return Optional.of(ConstantJwt.JWT_TOKEN_PREFIX + token);
    }

    /**
     * 解析令牌为会话
     *
     * @param token 令牌
     * @return 从令牌中解析后的会话
     */
    public static Optional<SessionInfo> parserJwt(String token) {

        if (StringUtils.isBlank(token)) {
            return Optional.empty();
        }

        Claims claims = Jwts.parser()
                .setSigningKey(ConstantJwt.JWT_SIGNING_KEY)
                .parseClaimsJws(token.replace(ConstantJwt.JWT_TOKEN_PREFIX, ""))
                .getBody();

        if (claims == null) {
            return Optional.empty();
        }

        SessionInfo sessionInfo = SessionInfo.builder().token(token).build();
        if (Objects.nonNull(claims.get(ConstantJwt.USER_ID))) {
            sessionInfo.setUserId(claims.get(ConstantJwt.USER_ID).toString());
        }

        if (Objects.nonNull(claims.get(ConstantJwt.LAST_REFRESH_TIMESTAMP))) {
            sessionInfo.setLastRefreshTimestamp(Long.parseLong(claims.get(ConstantJwt.LAST_REFRESH_TIMESTAMP).toString()));
        }

        return Optional.of(sessionInfo);
        // return Optional.of(SessionInfo.builder()
        //         .token(token)
        //         .userId(claims.get(ConstantJwt.USER_ID).toString())
        //         .category(UserCategoryEnum.valueOf(claims.get(ConstantJwt.USER_CATEGORY).toString()))
        //         .client(ClientCategoryEnum.valueOf(claims.get(ConstantJwt.CLIENT_CATEGORY).toString()))
        //         .lastRefreshTimestamp(Long.parseLong(claims.get(ConstantJwt.LAST_REFRESH_TIMESTAMP).toString()))
        //         .build());
    }

}
